package org.log4jeditor.xml.editor.utils;

import junit.framework.Assert;

import org.eclipse.core.resources.IFile;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.log4jconfig.xml.editor.utils.JdtUtils;
import org.log4jeditor.xml.editor.AbstractUITestCase;

public class JdtUtilsTestCase extends AbstractUITestCase {

	@Before
	public void setup() throws Exception {
		setupEditorConfiguration("log4j-jdtutils.xml");
	}
	
	@After
	public void tearDown() throws Exception {
		super.tearDownProject();
	}

	@Test
	public void testConstructor() {
		new JdtUtils();
	}
	
	@Test
	public void testGetJavaProjectOK() {
		IJavaProject project = JdtUtils.getJavaProject(document);
		Assert.assertNotNull(project);
		Assert.assertEquals("Wrong result", "TestProject", project.getElementName());
	}

	@Test
	public void testGetJavaProjectKONullParam() {
		Assert.assertNull("Unexpected not-null value", JdtUtils.getJavaProject(null));
	}

	@Test
	public void testGetFileOK() {
		IFile file = JdtUtils.getFile(document);
		Assert.assertNotNull(file);
		Assert.assertEquals("log4j-jdtutils.xml", file.getName());
	}

	@Test(expected=NullPointerException.class)
	public void testGetFileKONullArg() {
		JdtUtils.getFile(null);
	}

	@Test
	public void testGetTypeFromCurrentProjectOK() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.Logger");
		Assert.assertNotNull("Type not found", type);
	}

	@Test
	public void testGetTypeFromCurrentProjectOK2() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "test.TestAppender");
		Assert.assertNotNull("Type not found", type);
	}

	@Test
	public void testGetTypeFromCurrentProjectKOUnknownClassName() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "UnknownClassName");
		Assert.assertNull("Type found", type);

	}

	@Test
	public void testGetTypeHierarchyOK() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.Appender");
		Assert.assertNotNull(type);
		ITypeHierarchy hierarchy = JdtUtils.getTypeHierarchy(javaProject, type);
		Assert.assertNotNull(hierarchy);
		Assert.assertEquals("Invalid number of classes", 20, JdtUtils.getTypeHierarchy(javaProject, type).getAllClasses().length);
		

	}

	@Test
	public void testGetClassesFromTypeHierarchyOK() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.Appender");
		Assert.assertNotNull(type);
		ITypeHierarchy hierarchy = JdtUtils.getTypeHierarchy(javaProject, type);
		Assert.assertNotNull(hierarchy);
		Assert.assertEquals("Invalid number of classes in the hierarchy", 19, JdtUtils.getClassesFromTypeHierarchy(javaProject, type, hierarchy).size());
	}

	@Test
	public void testGetPackageFromQualifiedNameOK() {
		Assert.assertEquals("org", JdtUtils.getPackageFromQualifiedName("org"));
		Assert.assertEquals("org", JdtUtils.getPackageFromQualifiedName("org."));
		Assert.assertEquals("org", JdtUtils.getPackageFromQualifiedName("org.A"));
		Assert.assertEquals("org.apache", JdtUtils.getPackageFromQualifiedName("org.apache"));
		Assert.assertEquals("org.apache", JdtUtils.getPackageFromQualifiedName("org.apache."));
		Assert.assertEquals("org.apache", JdtUtils.getPackageFromQualifiedName("org.apache.App"));
		Assert.assertEquals("", JdtUtils.getPackageFromQualifiedName(null));
		Assert.assertEquals("", JdtUtils.getPackageFromQualifiedName("Appender"));
		Assert.assertEquals("", JdtUtils.getPackageFromQualifiedName("."));
		Assert.assertEquals("", JdtUtils.getPackageFromQualifiedName(""));

	}

	@Test
	public void testGetStaticFieldsFromTypeOK1() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.Level");
		Assert.assertEquals("Invalid number of static fields", 8, JdtUtils.getStaticFieldsFromType(type).size());
	}

	@Test
	public void testGetStaticFieldsFromTypeOK2() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.Priority");
		Assert.assertEquals("Invalid number of static fields", 5, JdtUtils.getStaticFieldsFromType(type).size());
	}

	@Test
	public void testGetAllSourcePackagesOK() throws Exception {
		Assert.assertEquals(2, JdtUtils.getAllSourcePackages(javaProject).size());
	}

	@Test
	public void testGetPackagesFromFragmentRoots() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 25, JdtUtils.getPackagesFromFragmentRoots(javaProject.getAllPackageFragmentRoots()).size());
	}

	@Test
	public void testGetClassesFromFragmentRootsOKMatchEmptyValue() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 0, JdtUtils.getClassesFromFragmentRoots(javaProject.getAllPackageFragmentRoots(), "").size());
	}

	@Test
	public void testGetClassesFromFragmentRootsOKMatchNullValue() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 0, JdtUtils.getClassesFromFragmentRoots(javaProject.getAllPackageFragmentRoots(), null).size());
	}

	@Test
	public void testGetClassesFromFragmentRootsOKMatchStringValueNoResult() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 0, JdtUtils.getClassesFromFragmentRoots(javaProject.getAllPackageFragmentRoots(), "org.apache").size());
	}

	@Test
	public void testGetClassesFromFragmentRootsOKMatchStringValue() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 34, JdtUtils.getClassesFromFragmentRoots(javaProject.getAllPackageFragmentRoots(), "org.apache.log4j").size());
	}

	@Test
	public void testGetClassesFromFragmentRootsOKMatchStringValue2() throws Exception {
		Assert.assertNotNull("jaaProject not found", javaProject);
		Assert.assertEquals("Invalid number of packages", 2, JdtUtils.getClassesFromFragmentRoots(javaProject.getAllPackageFragmentRoots(), "test").size());
	}

	@Test
	public void testGetMethodsWithJavadocFromType() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.ConsoleAppender");
		Assert.assertNotNull("Type not found", type);
		Assert.assertEquals("Invalid number of setters", 7, JdtUtils.getMethodsWithJavadocFromType(type).size());
	}

	@Test
	public void testGetSettableAttributes() throws Exception {
		IType type = JdtUtils.getTypeFromCurrentProject(javaProject, "org.apache.log4j.ConsoleAppender");
		Assert.assertNotNull("Type not found", type);
		Assert.assertEquals("Invalid number of setters", 7, JdtUtils.getSettableAttributes(type).size());
	}

}
